package com.dabai.markdownq.ui;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.Layout;
import android.text.Selection;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.FileProvider;

import com.dabai.dbutils.data.Patterns;
import com.dabai.dbutils.dialog.MdcDialog;
import com.dabai.dbutils.popup.menu.PopupMenuUtils;
import com.dabai.dbutils.qrcode.QRCodeUtils;
import com.dabai.dbutils.toast.DBToast;
import com.dabai.dbutils.utils.AssetsUtils;
import com.dabai.dbutils.utils.DabaiUtils;
import com.dabai.dbutils.utils.DateUtils;
import com.dabai.dbutils.utils.DebugUtils;
import com.dabai.dbutils.utils.FileUtils;
import com.dabai.dbutils.utils.SAFUtils;
import com.dabai.dbutils.utils.ShareUtils;
import com.dabai.dbutils.utils.SharedPreferencesBasicUse;
import com.dabai.dbutils.utils.SharedPreferencesUtils;
import com.dabai.dbutils.utils.StringUtils;
import com.dabai.dbutils.utils.UriUtils;
import com.dabai.dbutils.utils.component.ActivityUtils;
import com.dabai.markdownq.MainActivity;
import com.dabai.markdownq.R;
import com.dabai.markdownq.databinding.ActivityEditerBinding;
import com.dabai.markdownq.other.BoldSpan;
import com.dabai.markdownq.utils.MdTextUtils;
import com.dabai.markdownq.utils.OtherUtils;
import com.dabai.markdownq.utils.translate.TranslateCallback;
import com.dabai.markdownq.utils.translate.TranslateUtil;
import com.dabai.uitools.utils.ViewUtils;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import com.theartofdev.edmodo.cropper.CropImage;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;

import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.noties.markwon.Markwon;
import io.noties.markwon.editor.MarkwonEditor;
import io.noties.markwon.editor.MarkwonEditorTextWatcher;
import okhttp3.Call;
import ren.qinc.edit.PerformEdit;

public class EditorActivity extends AppCompatActivity {

    private String path;
    private Uri uri;

    Context context;
    ActivityEditerBinding aeb;
    private boolean isFile;
    private UriUtils uriUtils;
    private File file;

    String tmpContent;
    private PerformEdit mPerformEdit;


    Handler handler = new Handler();
    private Runnable autoSave;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        aeb = ActivityEditerBinding.inflate(getLayoutInflater());
        setContentView(aeb.getRoot());

        context = this;
        Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);

        try {
            init();
        } catch (Exception e) {
            new DebugUtils(this).showErrorMessage(e);
            finish();
        }


    }

    /**
     * 初始化
     *
     * @throws Exception 异常
     */
    private void init() throws Exception {

        SharedPreferencesBasicUse.init(context);

        Intent intent = getIntent();
        if (intent != null) {

            isFile = intent.getBooleanExtra("isFile", true);

            String title;
            String content;
            if (isFile) {
                path = intent.getStringExtra("path");
                file = new File(path);
                title = file.getName();
                content = FileUtils.readText(path);
            } else {
                uri = Uri.parse(intent.getStringExtra("path"));
                uriUtils = new UriUtils(context, uri);
                title = uriUtils.getFileName();
                content = uriUtils.readText();
            }
            //设置标题和内容
            setTitle(title);
            aeb.editText.setText(content);
            tmpContent = content;

            initEditor();

        } else {
            DBToast.showText(context, "编辑器加载失败!", false);
        }
    }

    /**
     * 初始化编辑器
     */
    private void initEditor() {

        aeb.editText.setTextSize(SharedPreferencesBasicUse.getFloat("textSize", 18));

        mPerformEdit = new PerformEdit(aeb.editText);

        if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("keyHighlight", false)) {

            final MarkwonEditor editor = MarkwonEditor.builder(Markwon.create(this))
                    .punctuationSpan(BoldSpan.class, BoldSpan::new)
                    .build();

            //基本代码高亮
            aeb.editText.addTextChangedListener(MarkwonEditorTextWatcher.withProcess(editor));

            aeb.editText.setText((getEditText() + "*").toCharArray(), 0, getEditText().length());

        }

        autoSave = new Runnable() {
            @Override
            public void run() {

                fileSave();

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("autoSave", false)) {
                    handler.postDelayed(this, 5000);
                }
            }
        };

        initTools();

        if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("autoSave", false)) {
            handler.post(autoSave);
        }
    }

    /**
     * 文件保存
     */
    private void fileSave() {

        //要做的事情
        if (isFile) {
            String content = getEditText();
            boolean saveResult = FileUtils.writeText(path, content);

            if (saveResult) {
                tmpContent = getEditText();
            }

        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler.removeCallbacks(autoSave);
    }


    /**
     * 初始化工具
     */
    private void initTools() {

        if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("atBottomTheToolbar", false)) {
            View toolView = findViewById(R.id.editorTools);
            LinearLayout linearLayout = findViewById(R.id.lineLayout);

            linearLayout.removeView(toolView);
            linearLayout.addView(toolView, 1);

        }

        if (DabaiUtils.isFunctionFirstOpen(this, "initTools")) {
            DabaiUtils.showDialog(context, "工具栏部分图标是可以长按的哦~").getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);
        }

        ImageButton tool_indentation = findViewById(R.id.tool_indentation);
        ImageButton tool_title = findViewById(R.id.tool_title);
        ImageButton tool_list_bulleted = findViewById(R.id.tool_list_bulleted);
        ImageButton tool_list_number = findViewById(R.id.tool_list_number);
        ImageButton tool_link = findViewById(R.id.tool_link);
        ImageButton tool_photo = findViewById(R.id.tool_photo);
        ImageButton tool_code = findViewById(R.id.tool_code);
        ImageButton tool_bold = findViewById(R.id.tool_bold);
        ImageButton tool_quotation = findViewById(R.id.tool_quotation);
        ImageButton tool_divider = findViewById(R.id.tool_divider);
        ImageButton tool_task_list = findViewById(R.id.tool_task_list);
        ImageButton tool_delete_line = findViewById(R.id.tool_delete_line);
        ImageButton tool_table = findViewById(R.id.tool_table);

        ImageButton tool_date = findViewById(R.id.tool_date);
        ImageButton tool_location = findViewById(R.id.tool_location);
        ImageButton tool_search = findViewById(R.id.tool_search);
        ImageButton tool_translation = findViewById(R.id.tool_translation);
        ImageButton tool_qr = findViewById(R.id.tool_qr);

        AtomicInteger tmpColumns = new AtomicInteger();

        tool_table.setOnClickListener(v -> {

            View diaView = ViewUtils.inflateLayout(context, R.layout.dialog_ins_table);

            TextInputLayout textInputLayout1 = diaView.findViewById(R.id.til1);
            TextInputLayout textInputLayout2 = diaView.findViewById(R.id.til2);

            AlertDialog alertDialog = new MaterialAlertDialogBuilder(context)
                    .setTitle("插入表格")
                    .setView(diaView)
                    .setNeutralButton("取消", null)
                    .setPositiveButton("插入", null)
                    .show();

            alertDialog.getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);
            alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v15 -> {

                String numberColumns = ViewUtils.getTextInputLayoutText(textInputLayout1);
                String numberRows = ViewUtils.getTextInputLayoutText(textInputLayout2);

                if (numberColumns.isEmpty() || numberRows.isEmpty()) {
                    DBToast.showYellowToast(context, "全部为必填项!");
                    return;
                }

                int columns = Integer.parseInt(numberColumns);
                int rows = Integer.parseInt(numberRows);

                if (columns == 0 || rows == 0) {
                    DBToast.showYellowToast(context, "均不能为0!");
                    return;
                }

                tmpColumns.set(columns);


                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                    if (!isEmptyLine(getEditText(), getSelectionStart())) {
                        insertText("\n\n");
                    }
                }

                insertText(MdTextUtils.returnInsertTableText(columns, rows));

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                    if (!isEmptyLine(getEditText(), getSelectionStart())) {
                        insertText("\n\n");
                    }
                }

                alertDialog.dismiss();
            });

        });
        tool_table.setOnLongClickListener(v -> {
            if (tmpColumns.get() == 0) {
                return false;
            }
            insertText(MdTextUtils.returnAddTableText(tmpColumns.get(), 1));
            return true;
        });

        tool_qr.setOnClickListener(v -> MdcDialog.showInputDialog(context, "转换为二维码", "", "请输入内容", new MdcDialog.OnInputDialogButtonListener() {
            @Override
            public void confirm(AlertDialog dialog, String content) {
                if (StringUtils.isEmpty(content)) {
                    DBToast.showYellowToast(context, "请输入内容!");
                    return;
                }
                File photoFile = new File(OtherUtils.getResourcesDir(context), DabaiUtils.getDeviceName(context) + "_QR_" + DateUtils.getNowTime(4) + ".jpg");
                insPhoto(QRCodeUtils.createSimpleQrCodeBitmap(content, 550, 550), photoFile, photoFile.getName());
                dialog.dismiss();
            }

            @Override
            public void cancel() {

            }
        }).getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS));
        tool_qr.setOnLongClickListener(v -> {
            QRCodeUtils.startQrCodeScanner(EditorActivity.this, 678);
            return true;
        });

        tool_photo.setOnLongClickListener(v -> {
            SAFUtils.openFile(EditorActivity.this, "image/*", 601);
            return true;
        });

        tool_search.setOnClickListener(v -> {

            View diaView = ViewUtils.inflateLayout(context, R.layout.dialog_replace);

            TextInputLayout textInputLayout1 = diaView.findViewById(R.id.til1);
            TextInputLayout textInputLayout2 = diaView.findViewById(R.id.til2);

            AlertDialog alertDialog = new MaterialAlertDialogBuilder(context)
                    .setTitle("替换文本")
                    .setView(diaView)
                    .setNeutralButton("取消", null)
                    .setPositiveButton("全部替换", null)
                    .show();

            if (isSelection()) {
                textInputLayout1.getEditText().setText(getSelectionText());
            }

            alertDialog.getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

            alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v14 -> {
                if (ViewUtils.getTextInputLayoutText(textInputLayout1).isEmpty()) {
                    DBToast.showText(context, "请输入被替换文本");
                    return;
                }

                try {
                    DBToast.showText(context, "共替换" + StringUtils.getAppearNumber(getEditText(), ViewUtils.getTextInputLayoutText(textInputLayout1)) + "处");
                } catch (Exception ignored) {
                }

                aeb.editText.setText(getEditText().replaceAll(ViewUtils.getTextInputLayoutText(textInputLayout1), ViewUtils.getTextInputLayoutText(textInputLayout2)));
                alertDialog.dismiss();
            });

        });
        tool_translation.setOnClickListener(v -> {

            View diaView = ViewUtils.inflateLayout(context, R.layout.dialog_translation);

            AlertDialog alertDialog = new MaterialAlertDialogBuilder(context)
                    .setTitle("Google翻译")
                    .setView(diaView)
                    .setCancelable(false)
                    .setNeutralButton("关闭", null)
                    .show();

            alertDialog.getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

            @SuppressLint("CutPasteId")
            TextInputLayout textInputLayout = diaView.findViewById(R.id.til1);

            if (isSelection()) {
                textInputLayout.getEditText().setText(getSelectionText());
            }

            Button b1 = diaView.findViewById(R.id.button1);
            Button b2 = diaView.findViewById(R.id.button2);

            b1.setOnClickListener(v13 -> {
                if (ViewUtils.getTextInputLayoutText(textInputLayout).isEmpty()) {
                    return;
                }
                new TranslateUtil().translate(context, "auto", "en", ViewUtils.getTextInputLayoutText(textInputLayout), new TranslateCallback() {
                    @Override
                    public void onTranslateDone(String result) {
                        if (isSelection()) {
                            delSelection();
                        }
                        insertText(result);
                        alertDialog.dismiss();
                    }
                });
            });
            b2.setOnClickListener(v13 -> {
                if (ViewUtils.getTextInputLayoutText(textInputLayout).isEmpty()) {
                    return;
                }
                new TranslateUtil().translate(context, "auto", "zh-CN", ViewUtils.getTextInputLayoutText(textInputLayout), new TranslateCallback() {
                    @Override
                    public void onTranslateDone(String result) {
                        if (isSelection()) {
                            delSelection();
                        }
                        insertText(result);
                        alertDialog.dismiss();
                    }
                });
            });

        });

        //缩进
        tool_indentation.setOnClickListener(v -> insertText('\u3000' + ""));
        //标题
        tool_title.setOnClickListener(v -> PopupMenuUtils.showPopupMenu(context, v, R.menu.editor_tool_title, new PopupMenuUtils.OnItemListener() {
            @Override
            public void clickItem(MenuItem item) {

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                    checkCurrentCursorLine();
                }

                switch (item.getTitle().toString()) {
                    case "H1":
                        insertText("# ");
                        SharedPreferencesBasicUse.setString("lastTimeTitle", "# ");
                        break;
                    case "H2":
                        insertText("## ");
                        SharedPreferencesBasicUse.setString("lastTimeTitle", "## ");
                        break;
                    case "H3":
                        insertText("### ");
                        SharedPreferencesBasicUse.setString("lastTimeTitle", "### ");
                        break;
                    case "H4":
                        insertText("#### ");
                        SharedPreferencesBasicUse.setString("lastTimeTitle", "#### ");
                        break;
                    case "H5":
                        insertText("##### ");
                        SharedPreferencesBasicUse.setString("lastTimeTitle", "##### ");
                        break;
                    case "H6":
                        insertText("###### ");
                        SharedPreferencesBasicUse.setString("lastTimeTitle", "###### ");
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onDismiss(PopupMenu menu) {

            }
        }));
        tool_title.setOnLongClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), SharedPreferencesBasicUse.getString("lastTimeTitle", "### "));
            } else {

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                    checkCurrentCursorLine();
                }
                insertText(SharedPreferencesBasicUse.getString("lastTimeTitle", "### "));
            }
            return true;
        });
        //无序列表
        tool_list_bulleted.setOnClickListener(v -> {

            if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                checkCurrentCursorLine();
            }
            insertText("- ");
        });
        //有序列表
        tool_list_number.setOnClickListener(v -> {

            if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                checkCurrentCursorLine();
            }
            insertText(list_number++ + ". ");
        });
        tool_list_number.setOnLongClickListener(v -> {
            list_number = 1;
            DBToast.showText(context, "计数器已清零!");
            return true;
        });
        //链接
        tool_link.setOnClickListener(v -> {
            View diaView = getLayoutInflater().inflate(R.layout.dialog_ins_link, null);
            TextInputLayout til1 = diaView.findViewById(R.id.til1);
            TextInputLayout til2 = diaView.findViewById(R.id.til2);

            AlertDialog insLinkDia = new MaterialAlertDialogBuilder(context)
                    .setTitle("插入链接")
                    .setView(diaView)
                    .setCancelable(false)
                    .setNeutralButton("取消", null)
                    .setPositiveButton("插入", null).show();
            insLinkDia.getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

            insLinkDia.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v12 -> {
                String title = Objects.requireNonNull(til1.getEditText()).getText().toString();
                String link = Objects.requireNonNull(til2.getEditText()).getText().toString();

                if (link.isEmpty()) {
                    DBToast.showText(context, "链接不能为空!", false);
                    return;
                }

                if (!StringUtils.startWith(link,
                        "http", "ftp", "file", "sms"
                        , "tel", "mailto", "ed2k"
                        , "news", "thunder")) {
                    DBToast.showYellowToast(context, "可能为非正常链接");
                }

                insertText("[" + (title.isEmpty() ? link : title) + "](" + link + ")");
                insLinkDia.dismiss();
            });

        });
        tool_link.setOnLongClickListener(v -> {
            String link = DabaiUtils.getClipboardContent(context);

            if (StringUtils.startWith(link, "sms", "tel", "mailto")) {
                try {
                    if (link.contains(":")) {
                        insertText("[" + link.split(":")[1] + "](" + link + ")");
                    }
                } catch (Exception e) {
                    insertText("[" + link + "](" + link + ")");
                }
                DBToast.showText(context, "已插入剪切板链接!");
                return true;
            }

            Matcher matcher = Patterns.WEB_URL.matcher(link);
            if (matcher.find()) {
                link = matcher.group();
                insertText("[" + link + "](" + link + ")");
                DBToast.showText(context, "已插入剪切板链接!");
            } else {
                DBToast.showYellowToast(context, "未检测到剪切板中的链接!");
            }
            return true;
        });
        //日期
        tool_date.setOnClickListener(v -> {
            AlertDialog insDateDialog = MdcDialog.showInputDialog(context, "插入时间", DabaiUtils.getSharedPreferencesString(context, "dateFormat", "yyyy-MM-dd HH:mm:ss"), "请输入时间格式", new MdcDialog.OnInputDialogButtonListener() {
                @Override
                public void confirm(AlertDialog dialog, String content) {

                    try {
                        insertText(DateUtils.getNowTime(content));
                        DabaiUtils.setSharedPreferencesString(context, "dateFormat", content);
                        dialog.dismiss();
                    } catch (Exception e) {
                        DBToast.showText(context, "格式异常!", false);
                    }

                }

                @Override
                public void cancel() {

                }
            });

            TextInputLayout textInputLayout = insDateDialog.findViewById(R.id.til1);

            insDateDialog.getButton(DialogInterface.BUTTON_POSITIVE).setText("插入");
            insDateDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setText("预览");
            insDateDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(v1 -> {

                String tmpDateText;
                try {
                    tmpDateText = DateUtils.getNowTime(Objects.requireNonNull(Objects.requireNonNull(textInputLayout).getEditText()).getText().toString());
                } catch (Exception e) {
                    tmpDateText = "格式异常!";
                }

                DBToast.showText(context, tmpDateText);
            });

        });
        tool_date.setOnLongClickListener(v -> {
            insertText(DateUtils.getNowTime(DabaiUtils.getSharedPreferencesString(context, "dateFormat", "yyyy-MM-dd HH:mm:ss")));
            return true;
        });
        //图片
        tool_photo.setOnClickListener(v -> SAFUtils.openFile(this, "image/*", 201));

        tool_code.setOnClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "```\n");
                insertText(getSelectionEnd(), "\n```");
            } else {

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                    checkCurrentCursorLine();
                }
                insertText("```\n\n```\n");
                aeb.editText.setSelection(aeb.editText.getSelectionStart() - 5);
            }

        });
        tool_code.setOnLongClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "`");
                insertText(getSelectionEnd(), "`");
            } else {
                insertText("``");
                aeb.editText.setSelection(aeb.editText.getSelectionStart() - 1);
            }

            return true;
        });
        tool_bold.setOnClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "**");
                insertText(getSelectionEnd(), "**");
            } else {
                insertText("****");
                aeb.editText.setSelection(aeb.editText.getSelectionStart() - 2);
            }

        });
        tool_bold.setOnLongClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "***");
                insertText(getSelectionEnd(), "***");
            } else {
                insertText("******");
                aeb.editText.setSelection(aeb.editText.getSelectionStart() - 3);
            }

            return true;
        });
        tool_quotation.setOnClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "> ");
            } else {

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                    checkCurrentCursorLine();
                }
                insertText("> ");
            }

        });

        tool_divider.setOnClickListener(v -> {
            insertText("\n-------\n");
        });

        tool_task_list.setOnClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "- [ ] ");
            } else {
                checkCurrentCursorLine();
                insertText("- [ ] ");
            }
        });
        tool_task_list.setOnLongClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "- [x] ");
            } else {
                checkCurrentCursorLine();
                insertText("- [x] ");
            }
            return true;
        });

        tool_delete_line.setOnClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "~~");
                insertText(getSelectionEnd(), "~~");
            } else {
                insertText("~~~~");
                aeb.editText.setSelection(aeb.editText.getSelectionStart() - 2);
            }
        });
        tool_delete_line.setOnLongClickListener(v -> {
            if (isSelection()) {
                insertText(getSelectionStart(), "<u>");
                insertText(getSelectionEnd(), "</u>");
            } else {
                insertText("<u></u>");
                aeb.editText.setSelection(aeb.editText.getSelectionStart() - 4);
            }
            return true;
        });
    }

    int list_number = 1;

    /**
     * 上传照片
     *
     * @param picFile 图片文件
     */
    public void uploadPicture(File picFile) {
        AlertDialog proDia = DabaiUtils.showDialog(context, "正在上传...");
        proDia.setCancelable(false);

        String url = "https://sm.ms/api/v2/upload/";
        String ua = "Mozilla/5.0 (Linux; Android ; M5 Build/MRA58K) MarkdownQ/1.0";

        HashMap<String, String> header = new HashMap<>();
        header.put("User-Agent", ua);

        OkHttpUtils.post()
                .url(url)
                .headers(header)
                .addFile("smfile", picFile.getName(), picFile)
                .addParams("ssl", "true")
                .build()
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Exception e, int i) {
                        proDia.dismiss();
                        DBToast.showText(context, "上传失败!" + e.getMessage(), false);
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        JSONObject requestJson;

                        try {
                            requestJson = new JSONObject(s);
                            JSONObject dataJson = requestJson.getJSONObject("data");
                            String url = dataJson.getString("url");

                            if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                                checkCurrentCursorLine();
                            }

                            insertText("![" + picFile.getName() + "](" + url + ")");

                            proDia.dismiss();
                            DBToast.showText(context, "上传成功!", true);
                            FileUtils.delete(picFile);

                        } catch (Exception e) {
                            proDia.dismiss();
                            DBToast.showText(context, "上传失败!" + e.getMessage(), false);
                            FileUtils.delete(picFile);
                        }
                    }
                });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == 201) {
                if (data != null) {
                    UriUtils photoUri = new UriUtils(context, data.getData());
                    File photoFile = new File(OtherUtils.getResourcesDir(context), DabaiUtils.getDeviceName(context) + "_" + photoUri.getFileName());

                    try {
                        insPhoto(photoUri.getBitmap(), photoFile, photoUri.getFileName());
                    } catch (IOException e) {
                        DBToast.showText(context, "插入图片异常:" + e.getMessage(), false);
                    }

                }
            }
            if (requestCode == 601) {
                if (data != null) {
                    CropImage.activity(data.getData())
                            .start(this);
                }
            }

            if (requestCode == 678) {
                if (data != null) {
                    String content = QRCodeUtils.getQrCodeScannerResult(data);
                    new MaterialAlertDialogBuilder(context)
                            .setTitle("扫描到的信息")
                            .setMessage(content)
                            .setNegativeButton("复制", (dialog, which) -> DabaiUtils.copyText(context, content))
                            .setPositiveButton("插入", (dialog, which) -> insertText(content))
                            .setNeutralButton("取消", null).show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);
                }
            }

            if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
                CropImage.ActivityResult result = CropImage.getActivityResult(data);
                assert result != null;
                Uri resultUri = result.getUri();
                UriUtils photoUri = new UriUtils(context, resultUri);
                File photoFile = new File(OtherUtils.getResourcesDir(context), DabaiUtils.getDeviceName(context) + "_crop_" + DateUtils.getNowTime(4) + ".jpg");

                try {
                    insPhoto(photoUri.getBitmap(), photoFile, photoFile.getName());
                } catch (IOException e) {
                    DBToast.showText(context, "插入图片异常:" + e.getMessage(), false);
                }
            }

        }

    }


    public void insPhoto(Bitmap bitmap, File photoFile, String fileName) {

        View diaView = LayoutInflater.from(context).inflate(com.dabai.dbutils.R.layout.dialog_save_image, null);
        ImageView imageView = diaView.findViewById(com.dabai.dbutils.R.id.imageView);
        imageView.setPadding(0, 20, 0, 0);

        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
            new Thread(() -> FileUtils.saveBitmap(bitmap, photoFile.getAbsolutePath())).start();
        }

        new MaterialAlertDialogBuilder(this)
                .setTitle("插入图片")
                .setView(diaView)
                .setPositiveButton("上传图床", (dialog, which) -> {
                    if (DabaiUtils.isFunctionFirstOpen(context, "uploadPhoto")) {
                        new MaterialAlertDialogBuilder(context).setTitle("提示")
                                .setMessage("本程序自带的图床使用的是SMMS图床，如需使用其他图床，请前往应用市场下载更多专用图床。" +
                                        "\n\n推荐图床:" +
                                        "\n- 小白图床\n- 咕咚云图")
                                .setPositiveButton("继续上传", (dialog1, which1) -> uploadPicture(photoFile))
                                .show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_Scale);
                    } else {
                        uploadPicture(photoFile);
                    }
                })
                .setNegativeButton("本地插入", (dialog, which) -> {
                    if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("toolbarWordWrap", false)) {
                        checkCurrentCursorLine();
                    }
                    insertText("![" + fileName + "](file://" + photoFile.getAbsolutePath() + ")");
                })
                .setNeutralButton("取消", null)
                .show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

    }

    private boolean hasNewLine(String source, int selectionStart) {
        if (source.isEmpty()) return true;
        source = source.substring(0, selectionStart);
        return source.charAt(source.length() - 1) == 10;
    }

    private boolean hasNewTwoLine(String source, int selectionStart) {
        source = source.substring(0, selectionStart);
        return source.length() >= 2 && source.charAt(source.length() - 1) == 10 && source.charAt(source.length() - 2) == 10;
    }

    private boolean isEmptyLine(String source, int selectionStart) {
        try {
            if (source.isEmpty()) return true;
            if (selectionStart == source.length()) return hasNewLine(source, selectionStart);

            String startStr = source.substring(0, selectionStart);
            //最后一行
            return source.charAt(startStr.length() - 1) == 10 && source.charAt(startStr.length()) == 10;
        } catch (Exception e) {
            return true;
        }
    }


    /**
     * 检查当前行, 如果有特殊符号 就换行
     */
    private void checkCurrentCursorLine() {

        if (!isEmptyLine(getEditText(), getSelectionStart())) {
            insertText("\n");
        }
    }

    //获取编辑框当前行
    private int getCurrentCursorLine(EditText editText) {
        int selectionStart = Selection.getSelectionStart(editText.getText());
        Layout layout = editText.getLayout();
        if (selectionStart != -1) {
            return layout.getLineForOffset(selectionStart) + 1;
        }
        return -1;
    }


    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.statisticalContent:
                statisticalContent();
                break;
            case android.R.id.home:
                checkFinish();
                break;
            case R.id.delContent:

                new MaterialAlertDialogBuilder(context)
                        .setTitle("警告")
                        .setMessage("是否要清空编辑框?")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                aeb.editText.setText("");
                            }
                        }).setNeutralButton("取消", null)
                        .show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

                break;
            case R.id.saveContent:
                save();
                break;
            case R.id.undo:
                mPerformEdit.undo();
                break;
            case R.id.redo:
                mPerformEdit.redo();
                break;
            case R.id.preview:

                fileSave();

                Intent intent = new Intent(this, MarkdownParsActivity.class);
                intent.putExtra("originalContent", getEditText());
                intent.putExtra("title", getTitle());
                startActivity(intent);

                if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("animatedTransitions", false)) {
                    overridePendingTransition(com.dabai.uitools.R.anim.push_ios_in, com.dabai.uitools.R.anim.push_ios_out);
                }
                break;
            case R.id.shareText:

                if (getEditText().isEmpty()) {
                    DBToast.showYellowToast(context, "啥也没有~");
                    break;
                }

                ShareUtils.shareText(context, getEditText());
                break;
            case R.id.shareMdFile:

                if (getEditText().isEmpty()) {
                    DBToast.showYellowToast(context, "啥也没有~");
                    break;
                }

                if (save()) {
                    if (isFile) {
                        ShareUtils.shareFile(context,
                                FileProvider.getUriForFile(context, getPackageName() + ".fileProvider", file),
                                "*/*");
                    } else {
                        ShareUtils.shareFile(context, uri, "*/*");
                    }
                }
                break;
            case R.id.shareHtmlFile:

                if (getEditText().isEmpty()) {
                    DBToast.showYellowToast(context, "啥也没有~");
                    break;
                }

                if (DabaiUtils.isFunctionFirstOpen(context, "shareHtmlFile")) {

                    new MaterialAlertDialogBuilder(context).setTitle("提示")
                            .setMessage("MD文档转为HTML文件功能尚不稳定，部分标签可能不能正常显示。")
                            .setPositiveButton("确定", (dialog, which) -> md2html_share()).show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);
                    break;
                }

                md2html_share();

                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * 统计内容
     */
    private void statisticalContent() {

        String totalContent = getEditText();


        DabaiUtils
                .showDialog(context, "统计", "总字数:" + totalContent.length()
                        + "\n行数:" + totalContent.split("\n").length
                        + "\n句数:" + StringUtils.getAnEndNum(totalContent)
                        + "\n中文字符数:" + StringUtils.getChineseNum(totalContent)
                        + "\n英文字符数:" + StringUtils.getEnglishNum(totalContent)
                        + "\n数字字符数:" + StringUtils.getNumberNum(totalContent)
                )
                .getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);
    }

    /**
     * md2html分享
     */
    private void md2html_share() {
        String htmlString = AssetsUtils.loadAssetsText(context, "md1.txt")
                + getTitle()
                + AssetsUtils.loadAssetsText(context, "md2.txt")
                + OtherUtils.escape(getEditText())
                + AssetsUtils.loadAssetsText(context, "md3.txt");
        File htmlFile = new File(OtherUtils.getTmpHtmlDir(context).getAbsolutePath(), StringUtils.removeFileSuffix(getTitle().toString()) + ".html");
        boolean isOk = FileUtils.writeText(htmlFile, htmlString);

        if (isOk) {
            ShareUtils.shareFile(context,
                    FileProvider.getUriForFile(context, getPackageName() + ".fileProvider", htmlFile),
                    "*/*");
        }
    }


    /**
     * 保存
     *
     * @return boolean
     */
    private boolean save() {
        boolean saveResult;
        String content = getEditText();

        if (isFile) {
            saveResult = FileUtils.writeText(path, content);
        } else {

            try {
                saveResult = uriUtils.rewriteText(content);
            } catch (Exception e) {
                saveResult = false;

                new MaterialAlertDialogBuilder(context)
                        .setTitle("保存失败")
                        .setMessage("此文件权限为只读，不能修改。是否另存到工作空间？")
                        .setPositiveButton("另存为", (dialog, which) -> createFile())
                        .setNeutralButton("取消", null)
                        .show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

            }

        }

        DBToast.showText(context, saveResult ? "保存成功!" : "保存失败!", saveResult);
        if (saveResult) {
            tmpContent = getEditText();
        }
        return saveResult;
    }


    /**
     * 创建文件
     */
    public void createFile() {

        AlertDialog alertDialog = MdcDialog.showInputDialog(context, "另存到工作空间", StringUtils.removeFileSuffix(uriUtils.getFileName()) + "_副本", "请输入文件名", new MdcDialog.OnInputDialogButtonListener() {
            @Override
            public void confirm(AlertDialog dialog, String content) {

                File tmpFile = new File(OtherUtils.getMarkdownFilesDir(context), content + ".md");

                if (!Objects.requireNonNull(tmpFile.getParentFile()).exists()) {
                    tmpFile.getParentFile().mkdirs();
                }

                if (content.toLowerCase().contains(".md")) {
                    DBToast.showText(context, "文件名不能包含后缀!", false);
                } else if (content.length() <= 0) {
                    DBToast.showText(context, "请输入文件名!", false);
                } else if (tmpFile.exists()) {
                    DBToast.showText(context, "该文件名已存在!", false);
                } else {
                    if (FileUtils.writeText(tmpFile, getEditText())) {
                        DBToast.showText(context, "创建成功!", true);

                        tmpContent = getEditText();

                        isFile = true;
                        file = tmpFile;
                        path = tmpFile.getAbsolutePath();
                        setTitle(tmpFile.getName());

                    } else {
                        DBToast.showText(context, "创建失败!", false);
                    }
                    dialog.dismiss();
                }
            }

            @Override
            public void cancel() {

            }
        });

        alertDialog.getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_IOS);

        TextInputLayout textInputLayout = alertDialog.findViewById(R.id.til1);
        assert textInputLayout != null;
        EditText editText = textInputLayout.getEditText();
        assert editText != null;
        editText.setSingleLine(true);

    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            checkFinish();
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("autoSave", false)) {
            fileSave();
        }
    }

    private void checkFinish() {

        if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("autoSave", false)) {
            fileSave();
        }

        if (!getEditText().equals(tmpContent)) {
            new MaterialAlertDialogBuilder(context)
                    .setTitle("提示")
                    .setMessage("你修改的内容尚未保存，请选择退出方式。")
                    .setNeutralButton("直接退出", (dialog, which) -> finish())
                    .setPositiveButton("保存并退出", (dialog, which) -> {
                        if (save()) {
                            finish();

                            if (getIntent().getBooleanExtra("isQuickCreate", false)) {
                                ActivityUtils.startActivity(context, MainActivity.class);
                            }
                        }
                    }).show().getWindow().setWindowAnimations(com.dabai.uitools.R.style.DBAnim_Transitions_Scale);
        } else {
            finish();

            if (getIntent().getBooleanExtra("isQuickCreate", false)) {
                ActivityUtils.startActivity(context, MainActivity.class);
            }

            if (SharedPreferencesUtils.getDefaultSharedPreferences(context).getBoolean("animatedTransitions", false)) {
                overridePendingTransition(com.dabai.uitools.R.anim.push_ios_in, com.dabai.uitools.R.anim.push_ios_out);
            }
        }
    }


    /**
     * 是否选择
     *
     * @return boolean
     */
    public boolean isSelection() {
        if (getSelectionStart() == getSelectionEnd()) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 选择开始
     *
     * @return int
     */
    public int getSelectionStart() {
        return aeb.editText.getSelectionStart();
    }

    /**
     * 会选择结束
     *
     * @return int
     */
    public int getSelectionEnd() {
        return aeb.editText.getSelectionEnd();
    }

    /**
     * 会选择结束
     *
     * @return int
     */
    public void delSelection() {
        aeb.editText.getEditableText().delete(getSelectionStart(), getSelectionEnd());
    }

    /**
     * 得到选择文本
     *
     * @return {@link String}
     */
    public String getSelectionText() {
        return getEditText().substring(getSelectionStart(), getSelectionEnd());
    }

    /**
     * 得到编辑框文本
     *
     * @return {@link String}
     */
    public String getEditText() {
        return aeb.editText.getText().toString();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.editor, menu);
        return super.onCreateOptionsMenu(menu);
    }

    public void insertText(String text) {
        int index = aeb.editText.getSelectionStart();
        Editable editable = aeb.editText.getText();
        editable.insert(index, text);
    }

    public void insertText(int index, String text) {
        Editable editable = aeb.editText.getText();
        editable.insert(index, text);
    }

}

